package com.agrimall.service.impl;

import com.agrimall.entity.User;
import com.agrimall.mapper.UserMapper;
import com.agrimall.service.UserService;
import com.agrimall.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;

import java.math.BigDecimal;
import java.security.MessageDigest;
import java.util.List;

/**
 * 用户服务实现类
 */
public class UserServiceImpl implements UserService {
    
    /**
     * MD5加密
     */
    private String md5(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(str.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException("MD5加密失败", e);
        }
    }
    
    @Override
    public User login(String username, String password) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = mapper.selectByUsername(username);
            if (user == null) {
                System.out.println("用户不存在: " + username);
                return null;
            }
            
            String inputPasswordMD5 = md5(password);
            String dbPassword = user.getPassword();
            
            System.out.println("登录尝试 - 用户名: " + username);
            System.out.println("输入密码MD5: " + inputPasswordMD5);
            System.out.println("数据库密码: " + dbPassword);
            System.out.println("密码匹配: " + inputPasswordMD5.equals(dbPassword));
            System.out.println("用户状态: " + user.getStatus());
            
            // 先检查密码
            if (!inputPasswordMD5.equals(dbPassword)) {
                return null; // 密码错误
            }
            
            // 密码正确，检查状态
            // 除了管理员（userType == 2），其他用户被禁用时不能登录
            if (user.getStatus() == 0 && user.getUserType() != 2) {
                // 普通用户或商户被禁用，返回null
                return null;
            }
            
            // 密码正确且状态正常（或管理员即使被禁用也可以登录）
            return user;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public boolean register(User user) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 检查用户名是否已存在
            if (mapper.selectByUsername(user.getUsername()) != null) {
                return false;
            }
            // 密码加密
            user.setPassword(md5(user.getPassword()));
            // 设置默认状态
            if (user.getStatus() == null) {
                user.setStatus(1);
            }
            int result = mapper.insert(user);
            sqlSession.commit();
            return result > 0;
        } catch (Exception e) {
            sqlSession.rollback();
            e.printStackTrace();
            return false;
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public User getUserById(Long userId) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.selectById(userId);
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public User getUserByUsername(String username) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.selectByUsername(username);
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public boolean updateUser(User user) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int result = mapper.update(user);
            sqlSession.commit();
            return result > 0;
        } catch (Exception e) {
            sqlSession.rollback();
            e.printStackTrace();
            return false;
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = mapper.selectById(userId);
            if (user == null || !user.getPassword().equals(md5(oldPassword))) {
                return false;
            }
            user.setPassword(md5(newPassword));
            int result = mapper.update(user);
            sqlSession.commit();
            return result > 0;
        } catch (Exception e) {
            sqlSession.rollback();
            e.printStackTrace();
            return false;
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public List<User> getUserList(int page, int pageSize) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int offset = (page - 1) * pageSize;
            return mapper.selectAll(offset, pageSize);
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public List<User> getUserListByType(Integer userType, int page, int pageSize) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int offset = (page - 1) * pageSize;
            return mapper.selectByUserType(userType, offset, pageSize);
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public boolean updateUserStatus(Long userId, Integer status) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = new User();
            user.setUserId(userId);
            user.setStatus(status);
            int result = mapper.update(user);
            sqlSession.commit();
            return result > 0;
        } catch (Exception e) {
            sqlSession.rollback();
            e.printStackTrace();
            return false;
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public BigDecimal getUserBalance(Long userId) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = mapper.selectById(userId);
            if (user != null && user.getBalance() != null) {
                return user.getBalance();
            }
            return BigDecimal.ZERO;
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public boolean rechargeBalance(Long userId, BigDecimal amount) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = mapper.selectById(userId);
            if (user == null || amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
                return false;
            }
            
            // 计算新余额
            BigDecimal currentBalance = user.getBalance() != null ? user.getBalance() : BigDecimal.ZERO;
            BigDecimal newBalance = currentBalance.add(amount);
            
            // 更新余额
            User updateUser = new User();
            updateUser.setUserId(userId);
            updateUser.setBalance(newBalance);
            int result = mapper.update(updateUser);
            sqlSession.commit();
            return result > 0;
        } catch (Exception e) {
            sqlSession.rollback();
            e.printStackTrace();
            return false;
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public boolean deductBalance(Long userId, BigDecimal amount) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = mapper.selectById(userId);
            if (user == null || amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
                return false;
            }
            
            // 获取当前余额
            BigDecimal currentBalance = user.getBalance() != null ? user.getBalance() : BigDecimal.ZERO;
            
            // 检查余额是否足够
            if (currentBalance.compareTo(amount) < 0) {
                return false;
            }
            
            // 计算新余额
            BigDecimal newBalance = currentBalance.subtract(amount);
            
            // 更新余额
            User updateUser = new User();
            updateUser.setUserId(userId);
            updateUser.setBalance(newBalance);
            int result = mapper.update(updateUser);
            sqlSession.commit();
            return result > 0;
        } catch (Exception e) {
            sqlSession.rollback();
            e.printStackTrace();
            return false;
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public int countAllUsers() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.countAll();
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public int countUsersByType(Integer userType) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.countByUserType(userType);
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public List<User> searchUsersByKeyword(String keyword, int page, int pageSize) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int offset = (page - 1) * pageSize;
            return mapper.selectByKeyword(keyword, offset, pageSize);
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public int countUsersByKeyword(String keyword) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.countByKeyword(keyword);
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public List<User> searchUsersByTypeAndKeyword(Integer userType, String keyword, int page, int pageSize) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int offset = (page - 1) * pageSize;
            return mapper.selectByTypeAndKeyword(userType, keyword, offset, pageSize);
        } finally {
            sqlSession.close();
        }
    }
    
    @Override
    public int countUsersByTypeAndKeyword(Integer userType, String keyword) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.countByTypeAndKeyword(userType, keyword);
        } finally {
            sqlSession.close();
        }
    }
}

